package com.tea.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.tea.Model.dto.WxShippingDTO;
import com.tea.Model.dto.DeliveryListDTO;
import com.tea.constans.ExpressCompanyMapping;
import com.tea.config.wx.WxShippingConfig;
import com.tea.utils.Result;
import com.tea.utils.WxUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 微信发货服务
 */
@Service
@Slf4j
public class WxShippingService {
    
    @Resource
    private WxShippingConfig wxShippingConfig;
    
    @Resource
    private RedisTemplate<String, String> redisTemplate;
    
    @Resource
    private ExpressCompanyMapping expressCompanyMapping;
    
    @Resource
    private WxUtil wxUtil;
    
    /**
     * 查询小程序是否开通发货信息管理服务
     * @param appid 小程序appid
     * @return 查询结果
     */
    public Result<?> isTradeManaged(String appid) {
        try {
            // 参数校验
            if (StrUtil.isBlank(appid)) {
                return Result.error("appid不能为空");
            }
            
            Result<?> result = wxUtil.executeWithTokenRetry(() -> doIsTradeManaged(appid));
            return result;
            
        } catch (Exception e) {
            log.error("查询小程序发货信息管理服务状态异常", e);
            return Result.error("查询异常: " + e.getMessage());
        }
    }
    
    /**
     * 执行查询小程序发货信息管理服务状态的具体逻辑
     * @param appid 小程序appid
     * @return 查询结果
     */
    private Result<?> doIsTradeManaged(String appid) {
        // 获取access token
        String accessToken = getAccessToken();
        
        // 构建请求URL
        String url = "https://api.weixin.qq.com/wxa/sec/order/is_trade_managed?access_token=" + accessToken;
        
        // 构建请求参数
        JSONObject requestBody = new JSONObject();
        requestBody.put("appid", appid);
        
        log.info("查询小程序发货信息管理服务状态，appid: {}", appid);
        
        // 发送请求
        HttpResponse response = HttpRequest.post(url)
                .body(requestBody.toJSONString())
                .contentType("application/json")
                .timeout(10000)
                .execute();
        
        if (!response.isOk()) {
            log.error("查询小程序发货信息管理服务状态请求失败，HTTP状态码: {}", response.getStatus());
            return Result.error("请求失败，HTTP状态码: " + response.getStatus());
        }
        
        String responseBody = response.body();
        JSONObject result = JSON.parseObject(responseBody);
        
        log.info("查询小程序发货信息管理服务状态响应: {}", responseBody);
        
        int errcode = result.getIntValue("errcode");
        if (errcode == 0) {
            // 成功
            boolean isTradeManaged = result.getBooleanValue("is_trade_managed");
            JSONObject data = new JSONObject();
            data.put("is_trade_managed", isTradeManaged);
            return Result.success(data);
        } else if (errcode == 40001) {
            // access_token失效，抛出异常触发重试
            String errmsg = result.getString("errmsg");
            log.warn("access_token失效，准备重试: errcode={}, errmsg={}", errcode, errmsg);
            throw new RuntimeException("ACCESS_TOKEN_INVALID: " + errmsg);
        } else {
            // 其他微信API错误
            String errmsg = result.getString("errmsg");
            log.error("查询小程序发货信息管理服务状态失败: errcode={}, errmsg={}", errcode, errmsg);
            return Result.error("查询失败: " + errmsg);
        }
    }
    
    /**
     * 获取微信Access Token
     * @return Access Token
     */
    public String getAccessToken() {
        return wxUtil.getAccessToken();
    }
    
    /**
     * 获取微信Access Token
     * @param forceRefresh 是否强制刷新token
     * @return Access Token
     */
    public String getAccessToken(boolean forceRefresh) {
        return wxUtil.getAccessToken(forceRefresh);
    }
    
    /**
     * 上传发货信息到微信
     * @param shippingDTO 发货信息
     * @return 上传结果
     */
    public Result<?> uploadShippingInfo(WxShippingDTO shippingDTO) {
        try {
            // 参数校验
            if (StrUtil.isBlank(shippingDTO.getTransactionId())) {
                return Result.error("微信支付交易单号不能为空");
            }
            
            if (StrUtil.isBlank(shippingDTO.getOpenId())) {
                return Result.error("用户openid不能为空");
            }
            
            return wxUtil.executeWithTokenRetry(() -> {
                String accessToken = getAccessToken();
                String url = wxShippingConfig.getApiUrl() + "?access_token=" + accessToken;
                
                // 构建请求参数
                JSONObject requestBody = buildShippingRequest(shippingDTO);
                
                log.info("上传微信发货信息，订单号: {}, 请求参数: {}", shippingDTO.getOrderNo(), requestBody.toJSONString());
                
                // 发送HTTP POST请求
                HttpResponse response = HttpRequest.post(url)
                        .body(requestBody.toJSONString())
                        .contentType("application/json")
                        .timeout(15000)
                        .execute();
                
                if (response.isOk()) {
                    String responseBody = response.body();
                    log.info("微信发货信息上传响应: {}", responseBody);
                    
                    // 解析响应
                    JSONObject result = JSON.parseObject(responseBody);
                    int errcode = result.getInteger("errcode");
                    if (errcode == 0) {
                        log.info("微信发货信息上传成功: {}", shippingDTO.getOrderNo());
                        return Result.success("发货信息上传成功");
                    } else if (errcode == 40001) {
                        // access_token失效，抛出异常触发重试
                        String errorMsg = result.getString("errmsg");
                        log.warn("access_token失效，准备重试: errcode={}, errmsg={}", errcode, errorMsg);
                        throw new RuntimeException("ACCESS_TOKEN_INVALID: " + errorMsg);
                    } else {
                        String errorMsg = result.getString("errmsg");
                        log.error("微信发货信息上传失败: {}, 错误码: {}, 错误信息: {}", 
                                 shippingDTO.getOrderNo(), errcode, errorMsg);
                        return Result.error("发货信息上传失败: " + errorMsg);
                    }
                } else {
                    log.error("微信发货信息上传请求失败，HTTP状态码: {}, 响应: {}", response.getStatus(), response.body());
                    return Result.error("发货信息上传请求失败");
                }
            });
            
        } catch (Exception e) {
            log.error("上传发货信息异常，订单号: {}", shippingDTO.getOrderNo(), e);
            return Result.error("发货信息上传异常: " + e.getMessage());
        }
    }
    
    /**
     * 构建微信发货请求参数
     * @param shippingDTO 发货信息
     * @return 请求参数JSON
     */
    private JSONObject buildShippingRequest(WxShippingDTO shippingDTO) {
        JSONObject request = new JSONObject();
        
        // 订单标识
        JSONObject orderKey = new JSONObject();
        orderKey.put("order_number_type", 2); // 使用微信支付单号
        orderKey.put("transaction_id", shippingDTO.getTransactionId());
        request.put("order_key", orderKey);
        
        // 发货模式和物流类型
//      UNIFIED_DELIVERY（统一发货）2、SPLIT_DELIVERY（分拆发货）
        request.put("delivery_mode", "UNIFIED_DELIVERY");
        //为了方便采用虚拟商品发货方式显示：1、实体物流配送 2、同城配送 3、虚拟商品，无实体配送形式 4、用户自提
        request.put("logistics_type", getLogisticsType(shippingDTO.getShippingMethod()));
        
        // 物流信息列表
        JSONArray shippingList = new JSONArray();
        JSONObject shipping = new JSONObject();
        
        // 快递信息
        if (StrUtil.isNotBlank(shippingDTO.getExpressNum())) {
            shipping.put("tracking_no", shippingDTO.getExpressNum());
        }
        
        if (StrUtil.isNotBlank(shippingDTO.getExpressCompany())) {
            String companyCode = expressCompanyMapping.getCompanyCode(shippingDTO.getExpressCompany());
            shipping.put("express_company", companyCode);
        }
        
        // 商品描述
        if (StrUtil.isNotBlank(shippingDTO.getItemDesc())) {
            shipping.put("item_desc", shippingDTO.getItemDesc());
        }
        
        // 联系方式
        JSONObject contact = new JSONObject();
        String consignorContact = StrUtil.isNotBlank(shippingDTO.getConsignorContact()) 
                ? shippingDTO.getConsignorContact() 
                : wxShippingConfig.getConsignorContact();
        contact.put("consignor_contact", consignorContact);
        shipping.put("contact", contact);
        
        shippingList.add(shipping);
        request.put("shipping_list", shippingList);
        
        // 上传时间
        String uploadTime = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) + "+08:00";
        request.put("upload_time", uploadTime);
        
        // 用户信息
        JSONObject payer = new JSONObject();
        payer.put("openid", shippingDTO.getOpenId());
        request.put("payer", payer);
        
        return request;
    }
    
    /**
     * 根据配送方式获取物流类型
     * @param shippingMethod 配送方式 0:外送 1:自提
     * @return 物流类型 1:实体物流配送采用快递公司进行实体物流配送形式 2:同城配送 3:虚拟商品 4:用户自提
     */
    private int getLogisticsType(String shippingMethod) {
        if ("1".equals(shippingMethod)) {
            return 4; // 用户自提
        } else {
            return 3; // 实体物流配送
        }
    }

}